package com.xmall.product.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xmall.product.define.dict.AttrOptionTypeEnum;
import com.xmall.product.define.dto.saleAttr.SpuSaleAttrDto;
import com.xmall.product.define.request.spu.SpuSaleAttrRequest;
import com.xmall.product.entity.AttrOption;
import com.xmall.product.entity.SpuSaleAttr;
import com.xmall.product.mapper.SpuSaleAttrMapper;
import com.xmall.product.service.IAttrOptionService;
import com.xmall.product.service.ISpuSaleAttrService;
import com.xmall.product.utils.ConvertUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 商品spu属性 服务实现类
 */
@Service
public class SpuSaleAttrServiceImpl extends ServiceImpl<SpuSaleAttrMapper, SpuSaleAttr> implements ISpuSaleAttrService {

    @Resource
    private IAttrOptionService attrOptionService;

    /**
     * 保存
     */
    @Transactional
    @Override
    public Map<Long, Long> save(Long spuId, List<SpuSaleAttrRequest> saleAttrs) {
        Map<Long, Long> attrIds = new HashMap<>();
        saleAttrs.forEach(saleAttr -> saleAttr.setSpuId(spuId));

        saleAttrs.forEach(saleAttr -> {
            SpuSaleAttr spuSaleAttr = ConvertUtils.SpuSaleAttrModule.INSTANCE.toEntity(saleAttr);
            this.save(spuSaleAttr);

            saleAttr.getOptionList().forEach(attrOption -> {
                attrOption.setAttrId(spuSaleAttr.getId());
                attrOption.setType(AttrOptionTypeEnum.SPU_SALE.getType());
                attrIds.put(attrOption.getAttrOptionSn(), spuSaleAttr.getId());
            });

            if(CollectionUtil.isNotEmpty(saleAttr.getOptionList())) {
                attrOptionService.saveBatch(
                    saleAttr.getOptionList().stream()
                    .map(attrOption -> ConvertUtils.AttrOptionModule.INSTANCE.toEntity(attrOption))
                    .collect(Collectors.toList())
                );
            }
        });
        return attrIds;
    }

    /**
     * 更新
     */
    @Transactional
    @Override
    public Map<Long, Long> update(Long spuId, List<SpuSaleAttrRequest> saleAttrs) {
        List<SpuSaleAttr> spuSaleAttrList = this.list(new QueryWrapper<SpuSaleAttr>().eq("spu_id", spuId));
        if(CollectionUtil.isNotEmpty(spuSaleAttrList)) {
            List<Long> attrIds = spuSaleAttrList.stream().map(SpuSaleAttr::getId).collect(Collectors.toList());
            List<Long> attrOptionIds = attrOptionService
                    .list(new QueryWrapper<AttrOption>().in("attr_id", attrIds))
                    .stream().map(AttrOption::getId).collect(Collectors.toList());

            this.removeBatchByIds(attrIds);
            if(CollectionUtil.isNotEmpty(attrOptionIds)) {
                attrOptionService.removeBatchByIds(attrOptionIds);
            }
        }
        return this.save(spuId, saleAttrs);
    }

    /**
     * 删除
     */
    @Transactional
    @Override
    public void delete(Long spuId) {
        List<SpuSaleAttr> spuSaleAttrs = this.list(new QueryWrapper<SpuSaleAttr>().eq("spu_id", spuId));
        if(CollectionUtil.isNotEmpty(spuSaleAttrs)) {
            List<Long> attrIds = spuSaleAttrs.stream().map(SpuSaleAttr::getId).collect(Collectors.toList());
            this.removeBatchByIds(attrIds);

            attrOptionService.remove(new QueryWrapper<AttrOption>().in("attr_id", attrIds).eq("type", AttrOptionTypeEnum.SPU_SALE.getType()));
        }
    }

    /**
     * 列表
     */
    @Override
    public List<SpuSaleAttrDto> listWithCascade(Long spuId) {
        return ConvertUtils.SpuSaleAttrModule.INSTANCE.doListToDtoList(this.baseMapper.listWithCascade(spuId));
    }
}
